#pragma once
#include <xplatform/XServerClient.h>
#include <xplatform/protobuf/xmsg_com.pb.h>
class XRegisterClient : public XServerClient
{
public:
    static XRegisterClient *Get()
    {
        static XRegisterClient *c = nullptr;
        std::unique_lock<std::mutex>(smutex_);
        if (!c)
            c = new XRegisterClient();
        return c;
    }
    XRegisterClient(const XRegisterClient &) = delete;
    XRegisterClient &operator=(const XRegisterClient &) = delete;
    /// @brief 注册服务,会和服务器建立连接
    void RegisterServer(const char *server_name, unsigned short server_port, const char *server_ip);
    /// @brief 发送获取微服务列表的请求,server_name==nullptr表示获取所有微服务
    void GetServiceReq(const char *server_name);

    // 接收服务的注册响应
    void RegisterRes(xmsg::XMsgHead *head, XMsg *msg);
    // 接收获取微服务列表的响应
    void GetServiceRes(xmsg::XMsgHead *head, XMsg *msg);
    static void MsgFuncCallback()
    {
        RegCB(xmsg::MSG_REGISTER_RES, (MsgCBFunc)&XRegisterClient::RegisterRes);
        RegCB(xmsg::MSG_GET_SERVICE_RES, (MsgCBFunc)&XRegisterClient::GetServiceRes);
    }
    /**
     * 获取所有服务的映射
     * 本函数用于获取当前所有已注册服务的映射信息 在内部有一个静态客户端映射指针 static_client_map，
     * @return 返回static_client_map，该对象包含所有服务的映射信息如果服务映射为空，则返回nullptr
     */
    xmsg::XServiceMap *GetAllService();
    /**
     * @brief 复制所有服务信息到一个新的XServiceMap对象中
     *
     * 该函数主要用于当需要获取当前所有服务的信息时调用它会返回一个包含所有服务信息的xmsg::XServiceMap对象
     * 在多线程环境下，该函数通过加锁来保证数据的一致性和完整性
     *
     * @return xmsg::XServiceMap 包含所有服务信息的XServiceMap对象如果static_server_map为空，则返回一个空的XServiceMap对象
     */
    xmsg::XServiceMap CopyAllService();
    /// @brief 获取指定服务名的所有服务信息（阻塞函数）
    /// 1.等待连接成功 2.发送获取微服务的信息 3.等待服务信息返回 4.返回服务信息
    /// @param service_name
    /// @param timeout_sec
    /// @return xmsg::XServiceMap::XServiceList
    xmsg::XServiceMap::XServiceList GetService(const char *service_name, int timeout_sec);
    //
    xmsg::XServiceMap::XServiceList GetService(const std::string &service_name, int timeout_sec = 10)
    {
        return GetService(service_name.c_str(), timeout_sec);
    }
    void Wait();

private:
    XRegisterClient()
    {
        setDeleteOnClose(false);
    }
    // 当客户端成功连接到服务器时调用此函数，发送注册请求消息
    void connectedCB() override;

private:
    // 线程不安全，需要对sttic_server_map加锁
    bool loadLocalFile();
    static std::mutex smutex_;
    // 微服务名
    char server_name_[1024];
    // 微服务端口
    unsigned short server_port_;
    // 微服务ip
    char server_ip_[32];
};